package com.oauth.twitter.server.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Required;

import com.oauth.common.server.OAuthGwtController;
import com.oauth.common.server.beans.OAuthAccessToken;
import com.oauth.common.server.beans.OAuthRequestToken;
import com.oauth.common.server.util.OAuthRequestUtil;
import com.oauth.components.client.beans.OAuthUrl;
import com.oauth.logging.OAuthLogger;
import com.oauth.twitter.client.beans.Tweet;
import com.oauth.twitter.client.beans.TwitterModel;
import com.oauth.twitter.client.beans.TwitterOAuthVerifier;
import com.oauth.twitter.client.exception.TwitterOAuthException;
import com.oauth.twitter.client.rpc.TwitterRemoteService;
import com.oauth.twitter.server.beans.TwitterRequestToken;
import com.oauth.twitter.server.constants.TwitterConstants;
import com.oauth.twitter.server.service.TwitterOAuthService;

public class TwitterGwtController extends OAuthGwtController implements TwitterRemoteService {

	private static final long serialVersionUID = -5758464341967618224L;

	private TwitterOAuthService mTwitterOAuthService;

	private OAuthLogger logger = OAuthLogger.getLogger(this.getClass());

	@Override
	public OAuthUrl getSignInUrl() throws TwitterOAuthException {
		TwitterRequestToken requestToken;
		try {
			requestToken = mTwitterOAuthService.getRequestToken();
		} catch (Exception e) {
			logger.error("Error in getting request token", e);
			throw new TwitterOAuthException();
		}
		OAuthRequestUtil.createTokenCookies(getHttpResponse(), requestToken,
				TwitterConstants.TWITTER_TOKEN_COOKIE, TwitterConstants.TWITTER_TOKEN_SECRETCOOKIE);
		OAuthUrl oauthUrl = new OAuthUrl();
		oauthUrl.setOAuthUrl(requestToken.getAuthorizationUrl());
		return oauthUrl;
	}

	@Override
	public Tweet updateTweet(String pTweetText) throws TwitterOAuthException {
		Tweet updatedTweet = null;
		try {
			updatedTweet = mTwitterOAuthService.updateTweet(pTweetText, OAuthRequestUtil
					.getMemberId(getHttpRequest()));
		} catch (Exception e) {
			logger.error("Error in updating tweet", e);
			throw new TwitterOAuthException();
		}
		return updatedTweet;
	}

	@Override
	public TwitterModel getTweets(TwitterOAuthVerifier pVerifier) throws TwitterOAuthException {
		TwitterModel model = new TwitterModel();
		Long memberId = OAuthRequestUtil.getMemberId(getHttpRequest());
		try {
			OAuthAccessToken accessToken = mTwitterOAuthService.getAccessTokenFromDB(memberId);
			if (accessToken == null) {
				/* Get request token from cookie. */
				OAuthRequestToken requestToken = OAuthRequestUtil.getOAuthTokenFromCookie(
						getHttpRequest(), TwitterConstants.TWITTER_TOKEN_COOKIE,
						TwitterConstants.TWITTER_TOKEN_SECRETCOOKIE);
				if (requestToken == null) {
					model.setLoginView(true);
					return model;// Go to login page, as there is no access
					// token in
					// db and no cookie.
				} else {
					accessToken = mTwitterOAuthService.getAccessTokenFromRequestToken(requestToken,
							pVerifier.getOAuthVerifier());

					/* Store access token for future use */
					mTwitterOAuthService.persistAccessToken(accessToken, memberId);
					deleteTwitterCookies();
				}
			}
			// finally you got the access token which is stored in db.
			logger.debug("Getting tweets for member=" + memberId);
			List<Tweet> tweets = mTwitterOAuthService.getTweets(memberId);
			model.setTweets(tweets);
			model.setUser(mTwitterOAuthService.getUserInfo(memberId));
			return model;
		} catch (Exception e) {
			deleteTwitterCookies();
			logger.error("Error in fetching tweets", e);
			e.printStackTrace();
			throw new TwitterOAuthException();
		}

	}

	private void deleteTwitterCookies() {
		OAuthRequestUtil.deleteTokenCookies(getHttpResponse(),
				TwitterConstants.TWITTER_TOKEN_COOKIE, TwitterConstants.TWITTER_TOKEN_SECRETCOOKIE);
	}

	/**
	 * @param pTwitterService
	 *            the twitterService to set
	 */
	@Required
	public void setTwitterOAuthService(TwitterOAuthService pTwitterService) {
		mTwitterOAuthService = pTwitterService;
	}

}
